//
//  UserInfoModel.m
//  芥子帝国
//
//  Created by 刘星辰 on 2018/3/15.
//  Copyright © 2018年 JZDG. All rights reserved.
//

#import "UserInfoModel.h"
#import <objc/runtime.h>
#import "UIPageDefines.h"

static NSString const *kPrefix = @"User_";

@implementation UserInfoModel
static UserInfoModel *_config = nil;
+(instancetype)alloc
{
    if (_config == nil)
    {
        _config = [super alloc];
    }
    return _config;
}
// 为了使实例易于外界访问 我们一般提供一个类方法
// 类方法命名规范 share类名|default类名|类名
+(instancetype)shareInstance
{
    // 也可以使用一次性代码
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (_config == nil) {
            _config = [[super alloc] init];
        }
    });
    return _config;
}
// 为了严谨，也要重写copyWithZone 和 mutableCopyWithZone
-(id)copyWithZone:(NSZone *)zone
{
    return _config;
}
-(id)mutableCopyWithZone:(NSZone *)zone
{
    return _config;
}


- (instancetype)init
{
    if (_config == nil)
    {
        _config = [super init];
        //初始化操作
        [self initialUserInfo];
    }
    return _config;
}


- (void)initialUserInfo
{
    unsigned int outCount, i;
    // class:获取哪个类的成员属性列表
    // count:成员属性总数
    // 拷贝属性列表
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    
    for (i = 0; i<outCount; i++)
    {
        objc_property_t property = properties[i];
        
        const char* char_f = property_getName(property);
        
        // 属性名
        NSString *propertyName = [NSString stringWithUTF8String:char_f];
        
        NSString *key = [NSString stringWithFormat:@"%@%@",kPrefix,propertyName];
        
         [self rebuildSetMethod:property];
        
        id value =  [USER_DEFAULT objectForKey:key];
        
        if (value == nil)
        {
            continue;
        }
        else
        {
            //赋值
            [self setValue:value forKey:propertyName];
            
        }
    }
    
    free(properties);
}


- (void)clearAllUserInfo
{
    unsigned int outCount, i;
    // class:获取哪个类的成员属性列表
    // count:成员属性总数
    // 拷贝属性列表
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    
    for (i = 0; i<outCount; i++)
    {
        objc_property_t property = properties[i];
        
        const char* char_f = property_getName(property);
        
        // 属性名
        NSString *propertyName = [NSString stringWithUTF8String:char_f];
        
        NSString *key = [NSString stringWithFormat:@"%@%@",kPrefix,propertyName];
        
        //赋值
        [USER_DEFAULT removeObjectForKey:key];
        
        if ([self isObject:property])
        {
            [self setValue:nil forKey:propertyName];
        }
        else
        {
            [self setValue:@(0) forKey:propertyName];
        }
        
    }
    
    free(properties);
}

- (void)rebuildSetMethod:(objc_property_t )property
{
    
    IMP imp = ([self isObject:property])?((IMP)ObjSetter):((IMP)Setter);
    
    NSString *method = [NSString stringWithFormat:@"set%@%@:",[self class], replaceString([NSString stringWithUTF8String:property_getName(property)])];
    
    NSString *method2 = [NSString stringWithFormat:@"set%@:", replaceString([NSString stringWithUTF8String:property_getName(property)])];
    
    
    if (class_addMethod([self class], NSSelectorFromString(method), imp, [self methodType:method2]))
    {
        class_replaceMethod([self class], NSSelectorFromString(method2), imp, [self methodType:method2]);
    }
}

- (const char *)methodType:(NSString *)method
{
    Method originMethod = class_getInstanceMethod([self class], NSSelectorFromString(method));
    return method_getTypeEncoding(originMethod);
}


void ObjSetter(id obj,SEL _cmdMe,id value)
{
    NSString *str = [NSStringFromSelector(_cmdMe) stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""];
    NSArray *arr = [str componentsSeparatedByString:@":"];
    
    NSString *var = arr.firstObject;
    var = replaceString(var);
    Ivar ivar = class_getInstanceVariable([obj class], [[NSString stringWithFormat:@"_%@",var] cStringUsingEncoding:NSUTF8StringEncoding]);
    if (ivar != nil)
    {
        object_setIvar(obj, ivar, [value copy]);
        [[NSUserDefaults standardUserDefaults] setObject:value forKey:[NSString stringWithFormat:@"%@%@",kPrefix,var]];
         [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

void Setter(id obj,SEL _cmdMe,long long value)
{
    NSString *str = [NSStringFromSelector(_cmdMe) stringByReplacingCharactersInRange:NSMakeRange(0, 3) withString:@""];
    NSArray *arr = [str componentsSeparatedByString:@":"];
    
    NSString *var = arr.firstObject;
    var = replaceString(var);
    Ivar ivar = class_getInstanceVariable([obj class], [[NSString stringWithFormat:@"_%@",var] cStringUsingEncoding:NSUTF8StringEncoding]);
    if (ivar != nil)
    {
        object_setIvar(obj, ivar, (__bridge id)((void *)value));
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithLongLong:value] forKey:[NSString stringWithFormat:@"%@%@",kPrefix,var]];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

NSString * replaceString(NSString * str)
{
    
    char cstr = [str characterAtIndex:0];
    
    char  temp ;
    if (cstr >= 'a' & cstr <= 'z')
    {
        temp  = cstr - 32;
    }
    else
    {
        temp  = cstr + 32;
    }
    NSRange range = NSMakeRange(0, 1);
    return [str stringByReplacingCharactersInRange:range withString:[NSString stringWithFormat:@"%c",temp]];
    //    }
    
    //    return @"setName";
}

- (BOOL)isObject:(objc_property_t)property
{
    
    NSString * attrStr = [NSString stringWithFormat:@"%@",[NSString stringWithUTF8String:property_getAttributes(property)]];
    NSArray * attrs = [attrStr componentsSeparatedByString:@","];
    for (NSString * str in attrs)
    {
        if ([str containsString:@"@"])
        {
            return YES;
        }
    }
    return NO;
}

- (void)test
{
        unsigned int count;
        //获取成员变量列表
        Ivar *ivarList = class_copyIvarList([self class], &count);
        for (unsigned int i = 0; i<count; i++) {
            Ivar myIvar = ivarList[i];
            const char *ivarName = ivar_getName(myIvar);
            NSLog(@"Ivar---->%@", [NSString stringWithUTF8String:ivarName]);
    //        NSLog(@"class ---->%@,value ---->%@",[object_getIvar(self, myIvar) class],object_getIvar(self, myIvar));
        }
    
//    NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
//    NSDictionary * dict = [defs dictionaryRepresentation];
//    for (id key in dict)
//    {
//        NSLog(@"%@ - %@",key,dict[key]);
//    }
//    [defs synchronize];
    
}

- (BOOL)isLoginState{
    BOOL isLogin = NO;
    if (UserInfo.userToken && UserInfo.userToken.length >0) {
        isLogin = YES;
    }else{
        isLogin = NO;
    }
    return isLogin;
}
@end
